home *** CD-ROM | disk | FTP | other *** search
- /*
- * CRITERR.C Demonstrate implementation and use of a
- * critical error handler.
- *
- * The purpose of CRITERR is to show a working example of
- * implementation and use of a critical error (int 0x24) handler.
- *
- * This program displays a prompt on the screen telling the user
- * to open the drive A: door, and then to press ENTER. The
- * program then attempts to open the file "A:\GARBAGE". This
- * will generate a critical error (int 0x24), which the program's
- * interrupt handler will respond to, by reporting the error, and
- * setting DOS to do a retry of the failed operation.
- *
- * The command line format is as follows:
- *
- * criterr
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1987, 1989
- *
- */
-
-
-
- #include <dos.h>
- #include <stdio.h>
-
- #include <bfiles.h>
- #include <bintrupt.h>
-
-
- #define CRIT_VEC 0x24
- #define STACKSIZE 3000 /* Items for the critical */
- #define NUMSTACKS 2 /* error ISR. */
-
- ISRCTRL crit_blk;
- char crit_stk[STACKSIZE*NUMSTACKS];
-
- void crit_err(ALLREG *,ISRCTRL *,ISRMSG *);
- void write_str(char *);
- void wait_key(void);
-
- void main()
- {
- char resp[2];
- FILE *file;
-
- /* Install DOS critical error handler. */
- isinstal (CRIT_VEC, crit_err, "TCT CRITER 5.00",
- &crit_blk, crit_stk, STACKSIZE, NUMSTACKS);
-
- /* Display message, wait for ENTER. */
- flprompt ("Open A: drive door, then press ENTER to test handler: ",
- resp, sizeof (resp));
-
- /* Now try to open (for reading) a file on drive A:.*/
- file = fopen ("a:\\garbage", "r");
-
- if (file != NULL)
- fclose (file);
-
- /* We do not have to re-install the previous */
- /* INT 0x24 handler because that happens */
- /* automatically on program termination. */
- }
-
-
-
- /**
- *
- * Name crit_err -- Handle DOS critical error
- *
- * Synopsis (To be called only from ISR dispatcher.)
- *
- * crit_err(pregs,pisrblk,pmsg);
- *
- * ALLREG *pregs Pointer to structure containing
- * register values in effect when
- * interrupt occurred.
- * ISRCTRL *pisrblk Pointer to control block for this
- * ISR.
- * ISRMSG *pmsg Pointer to structure containing
- * messages between this ISR and the
- * dispatcher.
- *
- * Description This function analyzes the information provided by DOS
- * in the machine registers, reports the error and the
- * device on which it occurs, and awaits a keystroke. It
- * returns to DOS in such a way as to request another
- * retry.
- *
- * Returns pregs->ax.hl.l Value 1, thereby requesting a retry.
- *
- **/
-
- void crit_err (pregs, pisrblk, pmsg)
- ALLREG *pregs;
- ISRCTRL *pisrblk;
- ISRMSG *pmsg;
- {
- DEV_HEADER dh;
- char report[100];
- int bad_fat;
-
- static char *message[] =
- {
- "Attempt to write on write-protected diskette", /* 0x00 */
- "Unknown unit", /* 0x01 */
- "Drive not ready", /* 0x02 */
- "Unknown command", /* 0x03 */
- "Data error (CRC)", /* 0x04 */
- "Bad request structure length", /* 0x05 */
- "Seek error", /* 0x06 */
- "Unknown media type", /* 0x07 */
- "Sector not found", /* 0x08 */
- "Printer out of paper", /* 0x09 */
- "Write fault", /* 0x0a */
- "Read fault", /* 0x0b */
- "General failure", /* 0x0c */
- "Unknown error 13", /* 0x0d */
- "Unknown error 14", /* 0x0e */
- "Invalid disk change" /* 0x0f */
- };
- static char *area[4] = /* Area on disk in which error */
- { /* may occur. */
- "DOS area (system files)",
- "file allocation table",
- "directory",
- "data area"
- };
-
- /* Get rid of compiler warning messages. */
- bad_fat = *((int *) pmsg);
- bad_fat = *((int *) pisrblk);
-
- bad_fat = 0;
-
- if (pregs->ax.hl.h & 0x80)
- { /* Character device or FAT error. */
-
- /* Get the device header into local storage. */
- utpeekn (uttofar (pregs->bp, pregs->si, char), &dh, sizeof (dh));
-
- /* If it is a character device, print its name. */
- if (dh.attr & 0x8000)
- sprintf (report,
- "\015\012<<Critical error on device \"%-.8s\":>>",
- dh.name);
-
- else /* It must be a block device FAT error. */
- {
- bad_fat = 1;
- sprintf (report, "\015\012<<Bad FAT on drive %c:>>",
- pregs->ax.hl.l + 'A');
- }
- }
- else /* Disk error. */
- sprintf(report,
- "\015\012<<Critical error while %s %s on drive %c:>>",
- (pregs->ax.hl.h & 1) ? "writing" : "reading",
- area[(pregs->ax.hl.h & 6) >> 1],
- pregs->ax.hl.l + 'A');
- write_str (report);
- write_str ("\015\012");
- write_str (message[utlobyte(pregs->di)]);
- write_str ("\015\012");
-
- write_str (report);
-
-
- if (bad_fat)
- write_str("\015\012<<BAD FAT -- Turn the computer off!\007\015\012>>");
-
- else
- {
- write_str ("\015\012Correct condition and press any key.\015\012");
- wait_key ();
- pregs->ax.hl.l = 1; /* Retry. */
- }
- }
-
-
-
- /**
- *
- * Name write_str -- Write string to DOS console using only DOS
- * functions 1-12. Ignore CTRL-BREAK.
- *
- * Synopsis write_str(pstring);
- *
- * char *pstring Pointer to beginning of character
- * array containing message to write.
- * The string must be terminated by NUL
- * ('\0') as usual.
- *
- * Description This function writes a string to the DOS console using
- * DOS functions 1-12 only. CTRL-BREAK and CTRL-C are
- * ignored.
- *
- * Returns (None. Function return type is void.)
- *
- **/
-
- void write_str(pstring)
- char *pstring;
- {
- union REGS regs;
- char ch;
-
- regs.x.ax = 0x0600;
- while ((ch = *pstring++) != '\0')
- {
- if (ch != (char) 0xff)
- {
- regs.x.dx = utbyword (0, ch);
- int86 (FL_DOS_INT, ®s, ®s);
- }
- }
- }
-
-
-
- /**
- *
- * Name wait_key -- Await keystroke and discard it.
- * (Use DOS functions 1-12 only.)
- *
- * Synopsis wait_key();
- *
- * Description This function discards any pending keystrokes, waits for
- * one more keystroke, and discards it. If the new
- * keystroke is CTRL-BREAK or CTRL-C, the program is
- * aborted.
- *
- * Returns (None. Function return type is void.)
- *
- **/
-
- void wait_key()
- {
- union REGS regs;
-
- regs.x.ax = 0x0c08; /* Flush keyboard & await one key. */
- int86 (FL_DOS_INT, ®s, ®s);
-
- /* If IBM PC extended character, read & discard the */
- /* second byte of the keystroke. */
- if (utlobyte (regs.x.ax) == 0)
- {
- regs.x.ax = 0x0600;
- regs.x.dx = 0x00ff;
- int86 (FL_DOS_INT, ®s, ®s);
- }
- }